iT邦幫忙

2021 iThome 鐵人賽

DAY 3
0
Modern Web

JavaScript學習日記系列 第 3

JavaScript學習日記 : Day3 - 基本型別(一)

  • 分享至 

  • xImage
  •  

1. 型別總覽

JavaScript中的數據都是有型別的,共有八種型別:

  • 數字(Number)
  • 字串(String)
  • 布林(Boolean)
  • Undefined
  • Null
  • Symbol
  • Bigint
  • Object

2. 型別介紹

2.1 Number

let n = 123;
n = 12.345;

number類型包含整數和小數,數字類型可以有很多操作,加減乘除等等。

除了一般的常規數字之外,也包含了特殊數值(special numeric value) --- Infinity,-Infinity和NaN。

2.1.1 Infinity代表數學概念中的無窮大。

我們可以透過除0得到

alert( 1 / 0 ); // Infinity

或是直接在代碼中使用:

alert( Infinity ); // Infinity

2.1.2 NaN代表計算錯誤或是一個未定義的數學操作結果。

alert( "some string" / 2 ); // NaN

對NaN進行任何操作都會返回NaN的。

在JavaScript中繼算是相對安全的,例如除以0或是將非數字字串視為數字等,都不會因此報錯,最壞的結果就是得到一個NaN。

2.2 BigInt

在JavaScript中,number類型無法表示大於2的53次方減一(即9007199254740991)或是小於-(2的53次方減一)的整數,在大多數情況這其實已經足夠,但如果必要時需要這個區間以外的整數時,可以將n附加在數字後面取得BigInt類型的值。

// 尾部的"n"表示這是一個BigInt類型
const bigInt = 1234567890123456789012345678901234567890n;

2.3 String

字串必須包含在引號內:

let str = "Hello";
let str2 = 'Single quotes are ok too';
let phrase = `can embed another ${str}`;

單引號跟雙引號基本上是沒什麼差別的,而反引號允許我們將變數或是表達式包裝在引號中的${}:

let name = "David";

// 加入一个變數
alert( `Hello, ${name}!` ); // Hello, David!

// 加入一個表達式
alert( `the result is ${1 + 2}` ); // the result is 3

2.4 Boolean

Boolean只包含True與False。

let nameFieldChecked = true; // yes, name field is checked
let ageFieldChecked = false; // no, age field is not checked

也可以作為比較的結果:

let isGreater = 4 > 1;

console.log( isGreater ); // true

2.5 Null

相較於其他語言,JavaScript中的null並不是對不存在的object的引用,JavaScript僅代表“無”“空”“未知”的特殊值。

2.6 Undefined

和null一樣自成類型,undefined的含義是為被賦值,如果一個變數被聲明,但是並未賦值,那他就是undefined。

let age;

console.log(age); // undefined

從技術上來講,可以將undefined賦值給一個變數:

let age = 100;

// 主動將值改為 undefined
age = undefined;

alert(age); // "undefined"

但不建議這麼做,通常會將null賦值給變數,而undefined則保留作為變數初始的默任值。

2.7 Symbol

symbol值表示唯一的識別符號,可以使用Symbol()來創建。

// id 是 symbol一個實例化的對象
let id = Symbol();

創建時也可以給Symbol一個描述(symbol名)

// id 是描述为 "id" 的 Symbol
let id = Symbol("id");

且symbol是保證唯一的:

let id1 = Symbol("id");
let id2 = Symbol("id");

alert(id1 == id2); // false

Symbol不會被自動轉換為字串
JavaScript大多都支持字符串的轉換,例如我們可以alert任何的值,都可以生效,但是symbol例外。

let id = Symbol("id");
alert(id); // 類型錯誤:無法將 Symbol 值轉換為字串。

這是一種防止混亂的語言保護,因為字符串跟symbol本質上不同,不應該轉換成為另一個。如果真的想要顯示出一個symbol:

let id = Symbol("id");
alert(id.toString()); // Symbol(id) 

或者獲取symbol.description,只顯示出描述:

let id = Symbol("id");
alert(id.description); // id

2.7.1 隱藏屬性

我們可以透過Symbol創建object的隱藏屬性,從外部是無法獲取這些屬性。

let cart = {
    userName: "John"
}

let id = Symbol("id");

cart[id] = 1;

console.log(cart[id])

使用Symbold("id")與使用字串"id"來新增主要的差別在於,如果cart是第三方的代碼,如果我們隨意新增屬性,是有可能影響到第三方的代碼,但是透過Symbol新增的屬性,第三方代碼中是獲取不到的。

另外,Symbol在for...in中是會被忽略的:

let id = Symbol("id")
let cart = {
    userName:"John",
    age:20,
    [id]:1
};

for(let key in cart) {
    console.log(key)
} // name, age

Object.keys()也一樣會忽略。但是Object.assign會複製symbol所創建的屬性:

let id = Symbol("id");
let person = {
    height:180,
    weight:70,
    [id]:10
}

let clonePerson = Object.assign({}, person);

console.log(clonePerson[id]);

2.7.2 全域的Symbol

所有的Symbol的值都是不同的,即使他們的名稱一樣,如果說我們想要讓有相同名子的Symbol返回相同的值,可以使用Symbol.for

Symbol.for(key)會從一個全域的Symbol註冊列表中搜尋有相同名稱的Symbol值,如果沒有就新增一個,並且放入全域註冊列表中。

let id = Symbol.for("id") // 不存在的話,就新增

let idA = Symbol.for("id"); // 獲取到id

console.log( id === idA); // true

還有另一個methodSymbol.keyFor是用來反查Symbol的名稱。

let idA = Symbol.for("userAId")
let idB = Symbol.for("userBId")

console.log(Symbol.keyFor(idA)) // userAId
console.log(Symbol.keyFor(idB)) // userBId

剩下的Object內容較多,明天再補充/images/emoticon/emoticon34.gif

參考資料:

JavaScript Info
Symbol
BigInt


上一篇
JavaScript學習日記 : Day2 - 動態型別+弱型別
下一篇
JavaScript學習日記 : Day4 - 基本型別(二)
系列文
JavaScript學習日記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言